package util;
import java.util.Map;
import java.util.List;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.text.SimpleDateFormat;
import java.security.MessageDigest;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.ResultSetMetaData;
import java.text.DecimalFormat;

/**
 * @author JFM
 */
public class MySQL
    {
    private static String url = null;
    private static String login = null;
    private static String password = null;
    private static Connection conn = null;
    private static Date ultimaAccion = null;

    static
		{
		url = "jdbc:mysql://localhost:3306/scheduler";
//		url = "jdbc:mysql://localhost:3306/scheduler_test";
//		login = "dpp_romipack";
//		password = "123456";
		login = "root";
		password = "";
		}

    public static String establecerConexion()
        {
        //Cargo los drivers para poder conectarme con la base de datos
        try{
           Class.forName("com.mysql.jdbc.Driver").newInstance();
           }catch(Exception e)
               { return "Hubo un problema al intentar cargar los drivers para acceder a la base de datos: \n\n"+e+"\n\nEs probable que no pueda conectarse con la base de datos."; }

        //Inicio la conexión con la base de datos
        try{
           conn = java.sql.DriverManager.getConnection(url,login,password);
		   conn.setAutoCommit(true);
           }catch(java.sql.SQLException e)
               { return "Hubo un problema al intentar establecer la conexión con la base de datos: \n\n"+e+"\n\nPara solucionar este problema: \na) Verifique la conectividad con el servidor \nb) Verifique que la url del servidor es correcta \nc) Verifique el nombre de usuario y el password para acceder al servidor son correctos"; }

        return null;
        }

	public static void verificarConexion() throws SQLException
		{
		Date ahora = new Date();

		// Si la conexion fue cerrada o nunca fue establecida, la establezco.
		if(conn == null || conn.isClosed() )
			{ establecerConexion(); }
		else
			{
			// Si pasaron mas de 10 minutos desde la ultima consulta, verifico que la conexion siga viva.
			if(ultimaAccion != null && ahora != null && ultimaAccion.getTime() < ahora.getTime() - (10*60*1000))
				{
				try{
					Statement stmt = conn.createStatement();
					ResultSet result = stmt.executeQuery("SELECT * FROM tipos_usuario LIMIT 1");
					if(result == null) { establecerConexion(); }
					}catch(Exception e) { establecerConexion(); }
				}
			}

		ultimaAccion = ahora;
		}



	// --- Metodos get()/set() --- //

	public static Connection getConnection()
		{
		try{ verificarConexion(); }catch(Exception e) {}
		return conn;
		}

	public static Statement getStatement() throws SQLException
		{
		try{ verificarConexion(); }catch(Exception e) {}
		return conn.createStatement();
		}

	public static ResultSet executeQuery(String query) throws SQLException
		{
		try{ verificarConexion(); }catch(Exception e) {}
		return conn.createStatement().executeQuery(query);
		}

	public static void executeUpdate(String query) throws SQLException
		{
		try{ verificarConexion(); }catch(Exception e) {}
		Statement stmt = conn.createStatement();
		stmt.executeUpdate(query);
		stmt.close();
		}

	public static List<Map> parseResult(ResultSet result) throws SQLException
		{
		List resultado = new LinkedList();		
		if(result != null)
			{
			ResultSetMetaData metaData = result.getMetaData();
			int columnas = metaData.getColumnCount();
			
			while(result.next())
				{
				Map fila = new HashMap();
				for(int i=0; i<columnas; i++)
					{ fila.put(metaData.getColumnLabel(i+1), result.getObject(i+1)); }
				resultado.add(fila);
				}
			}
		return resultado;
		}


	// --- Metodos format() --- //

    public static String format(Object param)
        {
        if(param == null || param.toString() == null || param.toString().length() == 0) return "null";
        if(param instanceof Date)
            {
            // Pongo la fecha en el unico formato aceptado por MySQL.
            return "\"" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date)param) + "\"";
            }
        else
            {
            // Si el parametro contiene comillas dobles, lo encierro en comillas simples en vez de en comillas dobles.
            if(param.toString().indexOf("\"")>=0) return "'"+param.toString()+"'";
            return "\""+param.toString()+"\"";
            }
        }

	public static String formatBit(boolean param)
		{ return (param)? "1" : "0"; }

    public static String formatDate(Object param)
        {
        if(param != null && param instanceof Date)
            {
            // Pongo la fecha en el unico formato aceptado por MySQL.
            return "\"" + new SimpleDateFormat("yyyy-MM-dd").format((Date)param) + "\"";
            }
        return "null";
        }

    public static String formatDateMin(Object param)
        {
        if(param != null && param instanceof Date)
            {
            // Pongo la fecha en el unico formato aceptado por MySQL.
            return "\"" + new SimpleDateFormat("yyyy-MM-dd 00:00:00").format((Date)param) + "\"";
            }
        return "null";
        }

    public static String formatDateMax(Object param)
        {
        if(param != null && param instanceof Date)
            {
            // Pongo la fecha en el unico formato aceptado por MySQL.
            return "\"" + new SimpleDateFormat("yyyy-MM-dd 23:59:59").format((Date)param) + "\"";
            }
        return "null";
        }

	private static DecimalFormat formatoDecimal = new DecimalFormat("#0.00;(-#0.00)");

    public static String formatDecimal(float param)
        { return formatoDecimal.format(param).replace(',', '.'); }

    public static String formatId(int id)
        { return (id > 0)? id+"" : "null"; }

	public static String formatId(String id)
        { return (id != null && id.length()>0 && id.compareTo("0")!=0)? id : "null"; }


	
    public static String toMD5(String cad)
        {
        if(cad == null || cad.length() == 0) return null;

        try{
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update( cad.getBytes() );
            byte[] hash = digest.digest();

            cad = "";
            for(int i=0; i<hash.length; i++)
                {
                cad += Integer.toHexString( (hash[i]<0)? hash[i]+255 : hash[i] );
                }
            }catch(Exception e){ cad = null; }

        return cad;
        }
	/*
	public static void main(String args[]) throws SQLException
		{
		ResultSet result = MySQL.executeQuery("SELECT ot.*, ov.* FROM ordenes_trabajo ot JOIN ordenes_venta ov ON ot.orden_venta_id = ov.id");
		List<Map> lista = MySQL.parseResult(result);
		for(int i=0; i<lista.size(); i++)
			{ System.out.println(lista.get(i)); }
		}
	*/
    }
